import { EventTouch } from 'cc';
import { Vec3 } from 'cc';
import { systemEvent } from 'cc';
import { input } from 'cc';
import { UITransform } from 'cc';
import { SystemEventType } from 'cc';
import { Vec2 } from 'cc';
import { Prefab } from 'cc';
import { Input } from 'cc';
import { _decorator, Component, Node ,Touch} from 'cc';
import { enemyComponent } from './enemy/enemyComponent';
import { roleComponent } from './role/roleComponent';
import { instantiate } from 'cc';
import { tween } from 'cc';
import { treeComponent } from './tree/treeComponent';
import { resourceManager, resourceType } from './resource/resourceManager';
const { ccclass, property } = _decorator;

const Horizontal = new Vec2(1, 0);

@ccclass('gameComponent')
export class gameComponent extends Component {

    @property(Node)
    targetNode: Node = null; // 目标节点，用于拖动

    @property(Node)
    roleNode : Node = null; // 目标节点，用于拖动

    @property(Node)
    fight_content : Node = null; // 目标节点，用于拖动

    @property(Node)
    effect_content : Node = null; // 目标节点，用于拖动

    @property(Prefab)
    hero_effect : Prefab = null; // 人物攻击效果

    @property(Prefab)
    enemy_effect : Prefab = null; // 敌人攻击效果

    @property(Prefab)
    meat_prefab : Prefab = null; // 肉

    private _content = [];

    private _startPos = new Vec2(0,0);

    private _touchPos = new Vec2(0,0);

    private _tempDelta = new Vec2(0,0);

    private _tempPos = new Vec2(0,0);
    
    onLoad() {
        
        this.initContentList();
        // 监听触摸事件
        this.node.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    initContentList(){
        for(let i in this.fight_content.children){
            this.fight_content.children[i]["unCheck"] = false;
            this._content.push(this.fight_content.children[i]);
        }
    }

    addContent(node){
        node["unCheck"] = false;
        this._content.push(node);
    }

    onDestroy() {
        // 移除触摸事件监听
        this.node.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.off(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    onTouchStart(event: EventTouch) {
        // 获取触摸点的世界坐标
        this._touchPos = event.getUILocation();
        this.setControlPosition(this._touchPos);
        this.roleNode.getComponent(roleComponent).setMoveStatus(true);
    }

    onTouchMove(event: EventTouch) {
        this._tempPos = event.getUILocation();
        Vec2.subtract(this._tempDelta,this._tempPos, this._touchPos);
        let distance = this._tempDelta.length();
        let rock_bg = this.targetNode.getChildByName("rock_bg");
        let rock = this.targetNode.getChildByName("rock");
        let radius = rock_bg.getComponent(UITransform).width / 2;
    
        const radian = this._tempDelta.angle(Horizontal);
    
        let x = Math.cos(radian) * (distance <= radius ? distance : radius);
        let y = Math.sin(radian) * (distance <= radius ? distance : radius);

        if(this._tempDelta.y < 0){
            x = Math.cos(radian) * (distance <= radius ? distance : radius);
            y = -Math.sin(radian) * (distance <= radius ? distance : radius);
        }
    
        rock.setPosition(new Vec3(x,y,0));
    
        //设置人物的方向
        this.roleNode.getComponent(roleComponent).changeRoleDir(new Vec2(x,y).normalize());
    }

    onTouchEnd(event: EventTouch) {
        this.resetControlPosition();
        this.roleNode.getComponent(roleComponent).setMoveStatus(false);
    }

    setControlPosition(worldPos){
        // 将世界坐标转换为目标节点的局部坐标
        const touchLocalPos = this.node.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(worldPos.x, worldPos.y, 0));
        // 设置目标节点的位置
        this.targetNode.active = true;
        this.targetNode.position = touchLocalPos;
    }

    resetControlPosition(){
        console.log("重置");
        this.targetNode.active = false;
        let rock = this.targetNode.getChildByName("rock");
        rock.setPosition(0,0,0);
        this._startPos = new Vec2(0,0);
    }

    //更新界面中的东西
    updateContentList(){
        let list = [];
        for(let i in this._content){
            if(this._content[i] != null && this._content[i] != undefined && this._content[i].isValid && !this._content[i]["unCheck"]){
                list.push(this._content[i]);
            }
        }

        this._content = list;
    }

    manageEmenyMove(hero : Node){
        let enemyList = [];
        for(let i in this._content){
            if(this._content[i].name.indexOf("enemy") > -1 && !this._content[i]["unCheck"]){
                enemyList.push(this._content[i]);
            }
        }

        if(enemyList.length <= 0) {
            console.log("==============界面中已经没有敌人了===============");
            return;
        }
        for(let i in enemyList){
            enemyList[i].getComponent(enemyComponent).updateEnemyPosition(hero);
        }
    }

    manageFightContentLayer(){

        let posList = [];

        //获取所有的节点y坐标
        for(let i in this._content){
            if(this._content[i]["unCheck"]) continue;
            let height = this._content[i].getComponent(UITransform).height;
            posList.push({
                index : parseInt(i),
                y : this._content[i].position.y - height / 2
            });
        }

        //对获取的坐标进行排序
        this.quickSortArray(posList,0,posList.length - 1);
        
        //设置所有的层级
        for(let i in posList){
            this._content[posList[i]["index"]].setSiblingIndex(parseInt(i));
        }
    }

    managerAttackEvent(){
        //检测英雄和Fight节点之前的状态
        let enemy = this.checkHerokAttackEnemy();
        let tree = this.checkHeroAttackTree();
        let resource = this.checkHeroGetResource();
        let build = this.checkHeroCloseBuild();
        if(enemy != null){
            this.roleNode.getComponent(roleComponent).attackEnemy(enemy);
        }else if(tree != null){
            this.roleNode.getComponent(roleComponent).attackTree(tree);
        }else if(resource != null){
            let type = resource.getComponent(resourceManager).curType;
            this.roleNode.getComponent(roleComponent).getResources(resource,type);
        }else if(build != null){

        }
    }

    //消失生成的道具
    dieCreateTool(target){
        
    }

    //英雄攻击敌人特效
    createHeroAttackEnemyEffect(hero,enemy){
        if(enemy["unCheck"]) return;
        let effect = instantiate(this.hero_effect);
        effect.setPosition(new Vec3(hero.position.x,hero.position.y,0));
        effect.parent = this.effect_content;
        tween(effect)
            .to(0.1,{position : new Vec3(enemy.position.x,enemy.position.y,0)})
            .call(()=>{
                effect.destroy();
                let heroPower = hero.getComponent(roleComponent).attackPower;
                if(!enemy["unCheck"]){
                    enemy.getComponent(enemyComponent).updateEnemyBlood(heroPower);
                }
            })
            .start();
    }

    //英雄攻击树特效
    createHeroAttackTreeEffect(hero,tree){
        if(tree["unCheck"]) return;
        let effect = instantiate(this.hero_effect);
        effect.setPosition(new Vec3(hero.position.x,hero.position.y,0));
        effect.parent = this.effect_content;

        tween(effect)
            .to(0.1,{position : new Vec3(tree.position.x,tree.position.y,0)})
            .call(()=>{
                effect.destroy();
                let heroPower = hero.getComponent(roleComponent).attackPower;
                if(!tree["unCheck"]){
                    tree.getComponent(treeComponent).updateTreeBlood(heroPower);
                }
            })
            .start();
    }

    //敌人攻击英雄特效
    createEnemyAttackHeroEffect(enemy){
        if(enemy["unCheck"]) return;
        let effect = instantiate(this.enemy_effect);
        effect.setPosition(new Vec3(enemy.position.x,enemy.position.y,0));
        effect.parent = this.effect_content;

        tween(effect)
            .to(0.1,{position : new Vec3(this.roleNode.position.x,this.roleNode.position.y,0)})
            .call(()=>{
                effect.destroy();
            })
            .start();
    }


    //英雄攻击敌人 敌人 > 树 > 投放道具
    checkHerokAttackEnemy(){
        let distance = 10000;
        let enemy = null;
        for(let i in this._content){
            if(this._content[i].name.indexOf("hero") < 0){
                //针对敌人的判断
                if(this._content[i].name.indexOf("enemy") > -1 && !this._content[i]["unCheck"]){
                    
                    let subPos = new Vec2();
                    let hero_pos = new Vec2(this.roleNode.position.x,this.roleNode.position.y);
                    let enemy_pos = new Vec2(this._content[i].position.x,this._content[i].position.y);

                    //计算人物和敌人之间偏移量
                    Vec2.subtract(subPos,hero_pos,enemy_pos);

                    //计算英雄和敌人范围
                    let range = subPos.length();

                    if(this.roleNode.getComponent(roleComponent).checkAttackEnemyRange(range)){
                        if(range <= distance){
                            distance = range;
                            enemy = this._content[i];
                        }
                    }
                }
            }
        }
        
        return enemy;
    }

    //英雄攻击树
    checkHeroAttackTree(){
        let distance = 10000;
        let tree = null;
        for(let i in this._content){
            if(this._content[i].name.indexOf("hero") < 0){
                //针对树的判断
                if(this._content[i].name.indexOf("tree") > -1 && !this._content[i]["unCheck"]){
                    
                    let subPos = new Vec2();
                    let hero_pos = new Vec2(this.roleNode.position.x,this.roleNode.position.y);
                    let enemy_pos = new Vec2(this._content[i].position.x,this._content[i].position.y);

                    //计算人物和树之间偏移量
                    Vec2.subtract(subPos,hero_pos,enemy_pos);

                    //计算英雄和树范围
                    let range = subPos.length();

                    if(this.roleNode.getComponent(roleComponent).checkAttackTreeRange(range)){
                        if(range <= distance){
                            distance = range;
                            tree = this._content[i];
                        }
                    }
                }
            }
        }

        return tree;
    }

    //敌人攻击英雄
    checkEnemyAttackHero(enemy){
        let subPos = new Vec2();
        let hero_pos = new Vec2(this.roleNode.position.x,this.roleNode.position.y);
        let enemy_pos = new Vec2(enemy.position.x,enemy.position.y);

        //计算敌人和英雄之间偏移量
        Vec2.subtract(subPos,hero_pos,enemy_pos);

        //计算英雄和敌人范围
        let range = subPos.length();

        if(enemy.getComponent(enemyComponent).checkAttackHeroRange(range)){
            enemy.getComponent(enemyComponent).attackHero(this.roleNode);
        }
    }

    //人物可以获取资源
    checkHeroGetResource(){
        let distance = 10000;
        let resource = null;
        for(let i in this._content){
            if(this._content[i].name.indexOf("hero") < 0){
                //针对掉落资源的判断
                if((this._content[i].name.indexOf("wood") > -1 || this._content[i].name.indexOf("meat") > -1 ) && !this._content[i]["unCheck"]){
                    
                    let subPos = new Vec2();
                    let hero_pos = new Vec2(this.roleNode.position.x,this.roleNode.position.y);
                    let resource_pos = new Vec2(this._content[i].position.x,this._content[i].position.y);

                    //计算人物和掉落资源之间偏移量
                    Vec2.subtract(subPos,hero_pos,resource_pos);

                    //计算英雄和掉落资源范围
                    let range = subPos.length();

                    if(this.roleNode.getComponent(roleComponent).checkCloseToTool(range)){
                        if(range <= distance){
                            distance = range;
                            resource = this._content[i];
                        }
                    }
                }
            }
        }

        return resource;
    }

    //人物靠近资源
    checkHeroCloseBuild(){
        let distance = 10000;
        let build = null;
        for(let i in this._content){
            if(this._content[i].name.indexOf("hero") < 0){
                //针对建筑的判断
                if(this._content[i].name.indexOf("build") > -1 && !this._content[i]["unCheck"]){
                    
                    let subPos = new Vec2();
                    let hero_pos = new Vec2(this.roleNode.position.x,this.roleNode.position.y);
                    let build_pos = new Vec2(this._content[i].position.x,this._content[i].position.y);

                    //计算人物和建筑之间偏移量
                    Vec2.subtract(subPos,hero_pos,build_pos);

                    //计算英雄和建筑范围
                    let range = subPos.length();

                    if(this.roleNode.getComponent(roleComponent).checkCloseToTool(range)){
                        if(range <= distance){
                            distance = range;
                            build = this._content[i];
                        }
                    }
                }
            }
        }

        return build;
    }

    update(deltaTime: number) {

       this.manageEmenyMove(this.roleNode);

       this.manageFightContentLayer();

       this.managerAttackEvent();
    
    }

    //快速排序
    quickSortArray(arr : number[],left : number,right : number){
        if(right <= left){
            return;
        }

        let i = left;
        let j = right + 1;
        let fact = arr[left];
        let cirterion = arr[left]["y"];

        while(true){
            while(arr[++i]["y"] > cirterion){
                if(i == right){
                    break;
                }
            }

            while(arr[--j] < cirterion){
                if(j == left){
                    break;
                }
            }

            if(i >= j){
                break;
            }

            let temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

        arr[left] = arr[j];
        arr[j] = fact;

        this.quickSortArray(arr,left,j - 1);
        this.quickSortArray(arr,j+1,right);
    }
}


